package top.zk123.chain.service.imp;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.poi.ss.usermodel.Workbook;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import top.zk123.chain.bean.Certificate;
import top.zk123.chain.bean.ReturnInfo;
import top.zk123.chain.bean.UploadPath;
import top.zk123.chain.bean.Verify;
import top.zk123.chain.bean.returnObj.CertOnChain;
import top.zk123.chain.exception.FileEmptyException;
import top.zk123.chain.exception.FileUploadException;
import top.zk123.chain.exception.WrongFileTypeException;
import top.zk123.chain.mapper.CertificateMapper;
import top.zk123.chain.mapper.VerifyMapper;
import top.zk123.chain.service.CertificateService;
import top.zk123.chain.service.VerifyService;
import top.zk123.chain.util.AESUtil;
import top.zk123.chain.util.ExcelWriter;
import top.zk123.chain.util.GlobalUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

import static top.zk123.chain.util.AESUtil.decode;
import static top.zk123.chain.util.GlobalUtils.JSON_PATH;
import static top.zk123.chain.util.GlobalUtils.TOMCAT_PATH;

/**
 * 验证相关 核心方法实现
 *
 * @author Ke Zhang
 * @since 2.0
 */
@Service
public class VerifyServiceImp implements VerifyService {
    @Resource
    VerifyMapper verifyMapper;
    @Resource
    CertificateMapper certificateMapper;
    @Resource
    CertificateService certificateService;

    @Override
    public ReturnInfo verifyCerts(MultipartFile[] files) throws FileEmptyException, WrongFileTypeException, FileUploadException {
        List<Verify> verifyList = new ArrayList<>();
        List<UploadPath> paths = GlobalUtils.filesUpload(files, TOMCAT_PATH + JSON_PATH);
        for (UploadPath path : paths) {
            Verify verify = new Verify();
            String filePath = TOMCAT_PATH + JSON_PATH + path.getNewFileName();
            File file = new File(filePath);
            StringBuffer buffer = new StringBuffer();
            try (Scanner sc = new Scanner(new FileReader(file))) {
                while (sc.hasNextLine()) {
                    buffer.append(sc.nextLine());
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
            String json = "";
            try {
                json = decode(AESUtil.key, buffer.toString());
                JSONObject jb = new JSONObject();
                jb = JSON.parseObject(json);
                verify.setCertType((String) jb.get("certType"));
                verify.setCertificateId((String) jb.get("certId"));
                verify.setSex((String) jb.get("sex"));
                verify.setName((String) jb.get("name"));
                verify.setCertificateUid(Long.parseLong(String.valueOf(jb.get("uid"))));
                verify.setFileName(path.getOriginFileName());
                verify.setUserId((String) jb.get("userId"));
                String result = "false";
                String fileHash = (String) jb.get("fileHash");
                List<CertOnChain> certsOnChain = certificateService.getCertsOnChain();
                for (CertOnChain cert : certsOnChain) {
                    if (cert.getFileHash().equals(fileHash)) {
                        result = "true";
                        break;
                    }
                }
                verify.setVerifyResult(result);
            } catch (Exception e) {
                verify.setCertType(null);
                verify.setCertificateId(null);
                verify.setSex(null);
                verify.setName(null);
                verify.setCertificateUid(0);
                verify.setFileName(path.getOriginFileName());
                verify.setUserId(null);
                verify.setVerifyResult("false");
            }
            verifyList.add(verify);
            verifyMapper.save(verify);
        }
        return new ReturnInfo(200, "success", JSON.toJSON(verifyList));
    }

    @Override
    public ReturnInfo getCertDetail(String UId) {
        long certUid = verifyMapper.findByUid(UId).getCertificateUid();
        Certificate cert = certificateMapper.findByCertUid(certUid);
        return new ReturnInfo(200, "证书详细信息查询成功", JSON.toJSON(cert));
    }

    @Override
    public ReturnInfo exportExcelAll(HttpServletRequest request, HttpServletResponse response) {
        List<Verify> dataList = verifyMapper.findVerify();
        exportExcel(request, response, dataList);
        return new ReturnInfo(200, "Excel导出成功", null);
    }


    @Override
    public ReturnInfo exportExcelSelected(HttpServletRequest request, HttpServletResponse response, List<String> UIdList) {
        List<Verify> dataList = new ArrayList<>();
        for (String s : UIdList) {
            Verify verify = verifyMapper.findByUid(s);
            if (null != verify) {
                dataList.add(verify);
            }
        }
        exportExcel(request, response, dataList);
        return new ReturnInfo(200, "Excel导出成功", null);
    }


    @Override
    public void exportExcel(HttpServletRequest request, HttpServletResponse response, List<Verify> dataList) {
        Workbook workbook = null;
        OutputStream out = null;
        try {
            // 生成Excel工作簿对象并写入数据
            workbook = ExcelWriter.exportData(dataList);

            // 写入Excel文件到前端
            String excelName = "示例Excel导出";
            String fileName = excelName + ".xls";
            fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), "iso8859-1");
            response.setHeader("Content-Disposition", "attachment;filename=" + fileName);
            response.setContentType("application/x-xls");
            response.setCharacterEncoding("UTF-8");
            response.addHeader("Pargam", "no-cache");
            response.addHeader("Cache-Control", "no-cache");
            response.flushBuffer();
            out = response.getOutputStream();
            workbook.write(out);
            out.flush();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != workbook) {
                    workbook.close();
                }
                if (null != out) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
